home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 25
/
Cream of the Crop 25.iso
/
compress
/
tar321__.zip
/
SOURCES.ZIP
/
SAVEFILE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-03-24
|
9KB
|
320 lines
/* savefile.c - storying regular files into (tape) archive
* This is the part of the Tar program (see file tar.c)
* Author: T.V.Shaporev
* Creation date 11 Mar 1993
*/
#include <stdio.h>
#include "sysup.h"
#include "modern.h"
#include "compress.h"
#include "zippipe.h"
#include "crc32.h"
#include "define.h"
extern char longname[];
extern char *deleft __ARGS__(( char * ));
extern void newhead __ARGS__(( char *, long ));
extern void prcsum __ARGS__(( register header * ));
extern void proctl __ARGS__(( char *, long ));
static void prhexl __ARGS__(( char *, long ));
static void prhexl(dest, l)
char *dest; long l;
{
register int i;
static char h[] = "0123456789AbCdEf";
*dest++ = '0'; *dest++ = 'x';
for (i=32; i;) *dest++ = h[(int)(l >> (i -= 4)) & 15];
*dest++ = ' '; *dest++ = '\0';
}
#ifdef UNIX
static werelost = FALSE;
#endif
#ifdef MSDOS
# include <string.h>
#else
int strlen();
char *strcpy(), *strcat(), *strncpy();
int open(), read(), close(), unlink();
long lseek();
#endif
#include "lzpack.h"
#include "roll.h"
void cantopen(name)
char *name;
{
(void)fprintf(myout, "Tar: can\'t open \'%s\'\n", name);
}
static void tmpput __ARGS__(( int ));
static void no_mem __ARGS__(( int ));
static void errproc __ARGS__(( char * ));
static void tmpput(c)
int c;
{
++codesize; if (rputc(c) != 0) errproc(hblock->m.name);
}
static void no_mem(flag)
int flag;
{
(void)fprintf(stderr, "No memory for encoding.");
if (flag) {
(void)fprintf(stderr, " Continue? ");
if (YES_NO()) return;
} else {
(void)fprintf(stderr, "\n");
}
done(ESMALL);
}
static void errproc(fname)
char *fname;
{
(void)fprintf(myout, "\nTar: error processing \'%s\'\n", fname);
done(EINTER);
}
void savefile(fname)
char *fname;
{
register i; register c;
register char *p;
register long blocks;
register packok;
register node *t; node *prev;
int infile; long this;
p = deleft(fname);
if (u_flag) {
if ((t = finditem(p, &prev, timehead)) != NONE) {
i = t->info.time >= st.st_mtime;
delitem(t, &timehead);
if (i) return;
}
}
if (isfile) { /* compare file to store with the archive */
#ifdef UNIX
if (st.st_ino == sa.st_ino && st.st_dev == sa.st_dev) return;
#endif
#ifdef MSDOS
if (isarchive(&st, fname)) return;
#endif
}
if (w_flag && !okwork('a', ' ', &st, fname)) return;
#ifdef MSDOS
infile = open(fname + fnoffset(fname), OM_RDONLY);
#else
infile = open(fname, OM_RDONLY);
#endif
if (infile < 0) {
cantopen(fname); return;
}
newhead(p, st.st_size);
#ifdef UNIX
if (st.st_nlink > 1) {
prev = t = linkhead; i = 1;
while (t && i>0) {
i = st.st_ino - t->info.data.inode;
if (!i) i = st.st_dev - t->info.data.device;
if (i>0) { prev = t; t = t->next; }
}
if (i || !t) {/* entry not found */
if ((t = additem(p, prev, &linkhead)) == NONE) {
if (!werelost) {
(void)fprintf(myout,
"Tar: out of memory; link(s) lost\n");
werelost = TRUE;
}
} else {
t->info.data.count = st.st_nlink - 1;
t->info.data.device = st.st_dev;
t->info.data.inode = st.st_ino;
}
} else {/* previous entry found */
(void)strncpy(hblock->m.linkname, t->name, MAXTNAME);
hblock->m.filetype = TF_LNK;
prcsum(hblock);
if (v_flag) {
(void)fprintf(myout, "a %s link to %s\n", p, t->name);
}
if (--(t->info.data.count) < 1) delitem(t, &linkhead);
(void)close(infile);
return;
}
}
#endif
blocks = (st.st_size + (BLKSIZE-1)) / BLKSIZE;
packok = FALSE;
if (blocks > 1) {
if (pktype == PKDEF) {
if (zipalloc()!=0 || newroll("TAROLLXXXXXX")!=0) {
delroll();
#ifndef MSDOS
if (!w_flag) {
no_mem(0);
} else
#endif
{
no_mem(1);
pktype = PKNONE;
goto run;
}
}
(void)rewroll(0);
if (v_flag) (void)fprintf(stderr, "e %s", p);
(void)fflush(stderr);
if (zipcreat(tmpput, ZIP_RAW, ziplevel) != 0) {
(void)fprintf(stderr, "Zip error: %s\n", ziperrlist[ziperror]);
done(EINTER);
}
this = 0;
do {
if ((i = read(infile, pk_inp, pksize)) < 0) {
errproc(hblock->m.name);
}
if (i > 0) {
(void)zipwrite(pk_inp, i);
if (v_flag) percent((this += i), st.st_size);
}
} while (i == pksize);
codesize = zipclose();
}
#ifdef USE_COMPRESS
else if (pktype == PKfLZW) {
if (strlen(hblock->m.name) > MAXTNAME-2) {
#ifndef MSDOS
if (!w_flag) {
(void)fprintf(stderr, longname, hblock->m.name);
} else
#endif
{
(void)fprintf(stderr,
"Tar: name \'%s\' too long. Store uncompressed? ",
hblock->m.name);
if (YES_NO()) goto run;
}
return;
}
if (newroll("TAROLLXXXXXX")!=0) {
delroll();
#ifndef MSDOS
if (!w_flag) {
no_mem(0);
} else
#endif
{
no_mem(1);
pktype = PKNONE;
goto run;
}
}
if ((i = z_gettab(lzwbits)) < lzwbits) {
if (i > 0) {
#ifndef MSDOS
if (!w_flag) {
(void)fprintf(stderr, "Can only handle %d bits.\n", i);
lzwbits = i;
} else
#endif
{
(void)fprintf(stderr,
"Can only handle %d bits. Continue? ", i);
lzwbits = YES_NO() ? i : -1;
}
}
if (i <= 0) {
no_mem(1);
z_reltab();
pktype = PKNONE;
goto run;
}
}
(void)rewroll(0);
if (v_flag) (void)fprintf(stderr, "z %s", p);
(void)fflush(stderr);
if (cbegin(lzwbits, tmpput, st.st_size) < lzwbits) no_mem(0);
this = 0;
do {
if ((i = read(infile, pk_inp, pksize)) < 0) {
errproc(hblock->m.name);
}
if (i > 0) {
cpiece(pk_inp, i);
if (v_flag) percent((this += i), st.st_size);
}
} while (i == pksize);
codesize = cflush();
}
#endif
if (v_flag) (void)fprintf(stderr, "\r");
if (pkfile) {
register long b;
if ((b = (codesize + (BLKSIZE-1)) / BLKSIZE) < blocks) {
packok = TRUE;
blocks = b;
} else if (lseek(infile, 0L, 0) < 0) {
(void)fprintf(myout, "Tar: \'%s\' seek error\n", fname);
done(ERREAD);
}
}
}
run : if (v_flag || j_flag) {
(void)fprintf(myout, "a %s %ld blocks\n", p, blocks);
}
if (j_flag) {
(void)fprintf(stderr, "> ");
for (i=0; (c=getc(myinp))!='\n'; ) {
if (i < sizeof(hblock->m.comment)-1) {
hblock->m.comment[i++] = c;
}
}
hblock->m.comment[i] = 0;
} else {
hblock->m.comment[0] = 0;
}
if (packok) {
proctl(hblock->m.size, codesize);
if (pktype == PKfLZW) {
(void)strcat(hblock->m.name, ".Z");
} else { /* pktype == PKDEF */
prhexl(hblock->m.srcsum, getcrc());
prhexl(hblock->m.srclen, st.st_size);
}
prcsum(hblock);
if (rewroll(1) != 0) errproc(p);
while (codesize-- > 0) {
if ((c = rgetc()) == EOF) errproc(p);
writebyte(c);
}
} else {/* common store file */
prcsum(hblock);
if ((blocks -= writearch(infile, st.st_size, fname)) != 0) {
(void)fprintf(myout, "Tar: \'%s\' decreased size\n", fname);
while (blocks-- > 0) nullblock(steptape());
}
}
(void)close(infile);
if (y_flag) {
#ifdef MDSOS
if (!(st.st_mode & S_IWRITE)) (void)chmod(fname, S_IWRITE);
#endif
if (unlink(fname)) {
(void)fprintf(myout, "Tar: can\'t delete \'%s\'\n", fname);
}
}
}